#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <string>
#include <cstring>
#include <cstdio>

using namespace std;

#define NUM 4

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int tickets = 1000;

struct ThreadData
{
    string threadname;
    
    ThreadData(int num)
    {
        threadname = "thread-" + to_string(num);
    }
};

void* getTickets(void* args)
{
    ThreadData* td = static_cast<ThreadData*>(args);
    const char* name = td->threadname.c_str();

    while(true)
    {
        pthread_mutex_lock(&mutex);
        if(tickets > 0)
        {
            usleep(1000);
            printf("who=%s get a ticket: %d\n", name, tickets);
            tickets--;
        }
        else
        {
            pthread_mutex_unlock(&mutex);
            break;
        }
        pthread_mutex_unlock(&mutex);
    }
    printf("%s is quit...\n", name);
    return nullptr;
}

int main()
{
    vector<pthread_t> tids;
    vector<ThreadData*> thread_datas;
    for(int i = 1; i <= NUM; ++i)
    {
        pthread_t tid;
        ThreadData* td = new ThreadData(i);
        thread_datas.push_back(td);
        pthread_create(&tid,nullptr,getTickets,td);
        tids.push_back(tid);
    }

    for(int i = 0; i < NUM; ++i)
    {
        pthread_join(tids[i],nullptr);
        delete thread_datas[i];
    }

    return 0;
}